package cn.uyunsky.platform.util.sql;

import java.util.*;
import java.util.Map.Entry;

/**
 * <p>Description: 每个冒号占位符sql对应的标准jdbc sql对象,
 *    可以获取其标准问号占位sql和参数名列表
 * </p>
 * @version 1.0
 * @author baiyh
 */
public class SqlPlan {

	String jdbcsql;
	NamedParameterMeta meta;

	public SqlPlan(String nameSql) {
		Map<Integer, String> nameDescription = ParameterRecognizer.parse(nameSql);

		//jdbcsql = nameSql;

		StringBuffer buffer = new StringBuffer();
		int start = 0;
		for (Iterator<Map.Entry<Integer, String>> iterator = nameDescription.entrySet().iterator(); iterator.hasNext();) {
			Entry<Integer, String> entry = iterator.next();
			Integer end = entry.getKey();
			String name = entry.getValue();
			buffer.append(nameSql.substring(start, end));
			buffer.append("?");

			start = end + name.length() + 1;
		}
		buffer.append(nameSql.substring(start, nameSql.length()));

		jdbcsql = buffer.toString();
		//		Collection<String> names = nameDescription.values();
		//		for (Iterator<String> iterator = names.iterator(); iterator.hasNext();) {
		//			String name = (String) iterator.next();
		//			//bug 将相同的字段给替换了....
		//			jdbcsql = jdbcsql.replaceAll(":".concat(name), "?");
		//		}
		meta = new NamedParameterMeta(nameDescription);
	}

	/**
	 * 将冒号占位符号的sql转换为?占位的sql;如果已缓存则在缓存中获取
	 * @return
	 */
	public String getPlanSql() {
		return jdbcsql;
	}

	public List<String> getNameList() {
		return meta.getNameList();
	}

	/**
	 * <p>Description: 每个nameSql的参数名和位置对照</p>
	 * @version 1.0
	 * @date 2011-9-14
	 */
	public static class NamedParameterMeta {

		/**
		  * @Fields nameDescription : 冒号占位符所在位置和占位符名称;
		  * 目前使用不需要此属性,去除此属性减少缓存内存占用
		  
		private Map<Integer, String> nameDescription = new HashMap<Integer, String>();
		*/

		/**
		  * @Fields nameList : 根据位置从小到大排序名称数组
		  */
		private List<String> nameList = new ArrayList<String>();

		public NamedParameterMeta(Map<Integer, String> nameDescription) {
			Object[] nameAry = nameDescription.keySet().toArray();
			Arrays.sort(nameAry);
			for (int i = 0; i < nameAry.length; i++) {
				nameList.add(nameDescription.get(nameAry[i]));
			}
		}

		public List<String> getNameList() {
			return nameList;
		}
	}

}
